package dbi.org.model;

import java.util.LinkedHashMap;

import dbi.org.exception.DbNameDoesntMatchException;
import dbi.org.exception.ReferenceToTableExists;
import dbi.org.exception.TableAlreadyExistsException;
import dbi.org.exception.TableCannotBeDropped;
import dbi.org.exception.TableDoesntExistsException;
import dbi.org.exception.TableDoesntMatchException;
import dbi.org.exception.TableNameEmptyException;

public class Database {
	private String name;
	private LinkedHashMap<String, Table> tables;

	public Database(String theName) {
		setName(theName);
		tables = new LinkedHashMap<String, Table>();
	}

	/**
	 * @return the naam
	 */
	public String getName() {
		return name;
	}

	/**
	 * @param theName
	 *            the naam to set
	 */
	public void setName(String theName) {
		this.name = theName;
	}

	/**
	 * Voeg een tabel toe
	 * 
	 * @param newTable
	 * @throws TableAlreadyExistsException
	 * @throws DbNameDoesntMatchException
	 * @throws Exception
	 */
	public void addTable(Table newTable) throws TableAlreadyExistsException,
			DbNameDoesntMatchException {
		if (newTable.getDbName().equals(name)) {
			if (tables.get(newTable.getTableName()) == null) {
				tables.put(newTable.getTableName(), newTable);
			} else {
				throw new TableAlreadyExistsException(newTable.getTableName());
			}
		} else {
			throw new DbNameDoesntMatchException();
		}
	}

	public void removeTable(String theName) throws TableNameEmptyException,
			TableDoesntExistsException, TableCannotBeDropped, ReferenceToTableExists {
		if (!theName.equals("")) {
			Table tableToRemove = tables.get(theName);
			if (tableToRemove != null) {
				if (tableToRemove.getRecords().size() == 0) {
					for(Table table : tables.values()) {
						for(Reference ref : table.getConstraint().getReferences().values()) {
							if(ref.fromGroup.tableName.equals(tableToRemove.getTableName())) {
								throw new ReferenceToTableExists("Er bestaat nog een referentie naar table: " + tableToRemove.getTableName() +" op Table: " +table.getTableName());
							} 
						}
					}
					tables.remove(tableToRemove.getTableName());
					
				} else {
					throw new TableCannotBeDropped("Table:"
							+ tableToRemove.getTableName()
							+ " bevat nog records");
				}
			} else {
				throw new TableDoesntExistsException();
			}
		} else {
			throw new TableNameEmptyException();
		}

	}

	public Table findTable(String tblName) throws TableNameEmptyException,
			TableDoesntExistsException {
		if (!tblName.equals("")) {
			Table tbl = tables.get(tblName);
			if (tbl != null) {
				return tbl;
			}
			throw new TableDoesntExistsException();
		}
		throw new TableNameEmptyException();
	}

	public LinkedHashMap<String, Table> getTables() {
		return tables;
	}

	public void changeTableName(String oldTableName, Table changedTable)
			throws TableNameEmptyException, TableDoesntExistsException, TableDoesntMatchException {
		Table tbl = this.findTable(oldTableName);
		if (tbl.equals(changedTable)) {
			tables.remove(oldTableName);
			tables.put(changedTable.getTableName(), changedTable);
		} else {
			throw new TableDoesntMatchException("Tabellen komen niet overeen");
		}
	}

	public void removeAll() {
		tables.clear();
	}

}
